/*
 * Copyright 2024 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include "commitstringdbus.h"

static const char backendName_[] = "org.fcitx.Fcitx5.CommitString";
static const char backendPatch_[] = "/commitstring";
static const char backendInterface_[] = "org.fcitx.Fcitx5.CommitString";

class CommitStringBackend
    : public fcitx::dbus::ObjectVTable<CommitStringBackend> {
public:
    explicit CommitStringBackend(CommitStringDBus *parent) : parent_(parent) {}

    ~CommitStringBackend() = default;

    void commitString(const std::string &str) { parent_->commitString(str); }

private:
    FCITX_OBJECT_VTABLE_METHOD(commitString, "CommitString", "s", "");

private:
    CommitStringDBus *parent_;
};

CommitStringDBus::CommitStringDBus(fcitx::Instance *instance)
    : instance_(instance), bus_(dbus()->call<fcitx::IDBusModule::bus>()),
      watcher_(*bus_) {
    initDBusInterface();
}

CommitStringDBus::~CommitStringDBus() {}

void CommitStringDBus::initDBusInterface() {
    commitStringBackend_ = std::make_unique<CommitStringBackend>(this);
    bus_->addObjectVTable(backendPatch_, backendInterface_,
                          *commitStringBackend_);

    bus_->requestName(backendName_,
                      fcitx::Flags<fcitx::dbus::RequestNameFlag>{
                          fcitx::dbus::RequestNameFlag::ReplaceExisting,
                          fcitx::dbus::RequestNameFlag::Queue});
    bus_->flush();
}

void CommitStringDBus::commitString(const std::string &text) {
    commitStringToCurrentWindow(text);
}

void CommitStringDBus::commitStringToCurrentWindow(const std::string &text) {
    fcitx::InputContext *inputContext = instance_->mostRecentInputContext();
    if (inputContext == nullptr) {
        FCITX_INFO() << "DBus Commit String Error: inputContext is null !";
    }

    inputContext->commitString(text);
}

void CommitStringDBus::commitStringToLastWindow(const std::string &text) {
    commitStringToCurrentWindow(text);
}

FCITX_ADDON_FACTORY(CommitStringDBusFactory)
